﻿#include "RegistrationAlgorithm.h"
#include "AesEncipher/AesEncipher.h"

#include <QDebug>
#include <QCryptographicHash>
#include <QNetworkInterface>
#include <QProcess>
#include <QMessageBox>
#include <QDateTime>
#include <QDate>
#include <QSettings>

namespace Core {

	RegistrationAlgorithm::RegistrationAlgorithm(QObject *parent)
		: QObject(parent)
	{

	}

	RegistrationAlgorithm::~RegistrationAlgorithm()
	{

	}

	QString RegistrationAlgorithm::getMachineCode()
	{
		QString CpuId = getCPUId();
		QString MacId = getMacId();
		QString UUId = getBaseUUid();

		QString UniqueCode = CpuId + MacId + UUId;

		QString MachineCode = "";

		for (int i = 0; i < UniqueCode.size(); i++)
		{
			MachineCode = MachineCode + UniqueCode[i];
			if ((i + 1) % 4 == 0 && i + 1 != UniqueCode.size())
			{
				MachineCode = MachineCode + "-";
			}
		}
		return MachineCode;
	}

	QString RegistrationAlgorithm::generateRegistrationCode(QString strEndDate, QString strMachineCode)
	{
		QString strTempData = strMachineCode + ";" + strEndDate;

		QString pubKey = QString("123456");
		GeneralAlgorithm::AESEncipher * t_pAESEncipher = new GeneralAlgorithm::AESEncipher(pubKey);
		QByteArray encodeArray = t_pAESEncipher->encode(strTempData.toLatin1());

		delete t_pAESEncipher;
		t_pAESEncipher = nullptr;

		return QString(encodeArray);
	}

	bool RegistrationAlgorithm::writeRegistrationCode(QString strRegistrationCode)
	{
		if (strRegistrationCode.isEmpty())
		{
			return false;
		}

		QString pubKey = QString("123456");
		GeneralAlgorithm::AESEncipher * t_pAESEncipher = new GeneralAlgorithm::AESEncipher(pubKey);
		QByteArray decodeArray = t_pAESEncipher->decode(strRegistrationCode.toLatin1());
		
		QString strTempData = QString(decodeArray);
		if (strTempData.isEmpty())
		{
			return false;
		}

		QStringList strList = strTempData.split(";");
		if (strList.isEmpty() || strList.size() != 2)
		{
			return false;
		}

		QString strMachineCode = strList.at(0);
		QString strEndDate = strList.at(1);
		
		// 写入系统注册表 或者 配置文件 配置文件
		QSettings settings("TestSoftware.ini", QSettings::IniFormat);
		settings.beginGroup("TestSoftware");
		settings.setValue("MachineCode", strMachineCode);
		settings.setValue("Deadline", strEndDate);
		settings.endGroup();

		return true;
	}

	bool RegistrationAlgorithm::verifyRegistrationCode(QString strRegistrationCode)
	{
		QString strMachineCode = getMachineCode();
		if (strRegistrationCode != strMachineCode)
		{
			return false;
		}

		return true;
	}

	bool RegistrationAlgorithm::verifyRegistration()
	{
		// 读取 系统注册表 或者 配置文件 配置文件
		QSettings settings("TestSoftware.ini", QSettings::IniFormat);
		QString strMachineCode = settings.value("TestSoftware/MachineCode").toString();
		QString strEndDate = settings.value("TestSoftware/Deadline").toString();
		if (strMachineCode.isEmpty() || strEndDate.isEmpty())
		{
			return false;
		}

		if (!verifyRegistrationCode(strMachineCode))
		{
			return false;
		}

		QDateTime time1 = QDateTime::fromString(strEndDate, "yyyy-MM-dd");
		QDateTime time2 = QDateTime::currentDateTime();
		int days = time2.daysTo(time1);
		if (days < 0)
		{
			return false;
		}

		return true;
	}

	QString RegistrationAlgorithm::getCPUId()
	{
		QString strCpuId = "";
		unsigned int dwBuf[4] = { 0 };
		unsigned long long ret = 0;

		__cpuid((int*)(void*)dwBuf, 1);

		ret = dwBuf[3];
		ret = ret << 32;

		QString str0 = QString::number(dwBuf[3], 16).toUpper();
		QString str0_1 = str0.rightJustified(8, '0');
		QString str1 = QString::number(dwBuf[0], 16).toUpper();
		QString str1_1 = str1.rightJustified(8, '0');
		strCpuId = str0_1 + str1_1;
		return strCpuId;
	}

	QString RegistrationAlgorithm::getMacId()
	{
		QList<QNetworkInterface> nets = QNetworkInterface::allInterfaces();
		int nCnt = nets.count();
		QString strMacAddr = "";
		for (int i = 0; i < nCnt; i++)
		{
			if (nets[i].flags().testFlag(QNetworkInterface::IsUp)
				&& nets[i].flags().testFlag(QNetworkInterface::IsRunning)
				&& !nets[i].flags().testFlag(QNetworkInterface::IsLoopBack))
			{
				for (int j = 0; j < nets[i].addressEntries().size(); j++)
				{
					if (nets[i].addressEntries().at(j).ip() != QHostAddress::LocalHost && nets[i].addressEntries().at(j).ip().protocol() == QAbstractSocket::IPv4Protocol)
					{
						strMacAddr = nets[i].hardwareAddress();
					}
				}
			}
		}
		strMacAddr.remove(':');
		return strMacAddr;
	}

	QString RegistrationAlgorithm::getSystemId(const QString & cmd)
	{
		QProcess p;
		p.start(cmd);
		p.waitForFinished(-1);
		QString result = QString::fromLocal8Bit(p.readAllStandardOutput());
		QStringList list = cmd.split(" ");
		result = result.remove(list.last(), Qt::CaseInsensitive);
		result = result.replace("\r", "");
		result = result.replace("\n", "");
		result = result.simplified();
		p.close();

		if (result == "")
		{
			QMessageBox::warning(nullptr, u8"提示", u8"获取系统Id失败");
		}
		return result.trimmed();
	}

	QString RegistrationAlgorithm::getBaseUUid()
	{
		QString temp = getSystemId("wmic csproduct get uuid");
		QString uuid = temp.replace("-", "");
		return uuid;
	}

}//namespace Core